package com.gph.saviorframework.security.web.controller;

import com.alibaba.fastjson.JSONObject;
import com.gph.saviorframework.OaConstants;
import com.gph.saviorframework.SaviorFrameworkException;
import com.gph.saviorframework.common.model.Role;
import com.gph.saviorframework.security.service.*;
import com.gph.saviorframework.uitl.SecurityUtils;
import com.gph.saviorframework.util.RequestUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/" + OaConstants.FRAMEWORK_REQUEST_PATH + "/role")
public class RoleController {

    /**
     * 日志输出
     */
    final Logger logger = LoggerFactory.getLogger(RoleController.class);

    /**
     * 领域对象名称
     */
    private final String domain = Role.class.getSimpleName().toLowerCase();

    /**
     * 视图前缀
     */
    private final String viewPrefix = OaConstants.FRAMEWORK_REQUEST_PATH + "/" + OaConstants.MODULE_CATEGORY_SECURITY + "/" + domain + "/" + domain + "_";

    @Autowired
    private RoleService roleService;

    @Autowired
    private FunctionService functionService;

    @Autowired
    private MenuService menuService;

    @Autowired
    private UserService userService;

    @Autowired
    private OrgService orgService;

    @Autowired
    private MessageSourceAccessor messages;

    @Autowired
    private SecurityUtils securityUtils;

    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public String indexPage() throws SaviorFrameworkException {
        return viewPrefix + "index";
    }

    @RequestMapping(value = "/index", method = RequestMethod.POST)
    @ResponseBody
    public String list(
            @RequestParam(value = OaConstants.DEFAULT_PAGE_MODEL_KEY, required = false, defaultValue = OaConstants.DEFAULT_PAGE_START) Integer start,
            @RequestParam(value = OaConstants.DEFAULT_RECORD_MODEL_KEY, required = false, defaultValue = OaConstants.DEFAULT_PAGE_SIZE) Integer limit,
            @RequestParam(value = OaConstants.DEFAULT_SORT_MODEL_KEY, required = false, defaultValue = OaConstants.DEFAULT_SORT_FIELD) String sort,
            @RequestParam(value = OaConstants.DEFAULT_DIR_MODEL_KEY, required = false, defaultValue = OaConstants.DEFAULT_SORT_DIRECTION) String dir,
            HttpServletRequest request) throws SaviorFrameworkException {
        String json = "";
        Map<String, Object> params = RequestUtil.getQueryMap(request, roleService.getFields());
        try {
            json = JSONObject.toJSONString(roleService.find(start, limit, sort, dir, params));
            logger.info(messages.getMessage("log.info.list", new String[]{securityUtils.getUserFullName(), messages.getMessage(domain)}));
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(messages.getMessage("log.error.list", new String[]{securityUtils.getUserFullName(), messages.getMessage(domain)}));
        }
        return json;
    }

    @RequestMapping(value = "/create", method = RequestMethod.GET)
    public String createPage() throws SaviorFrameworkException {
        return viewPrefix + "create";
    }

    @RequestMapping(value = "/create", method = RequestMethod.POST)
    @ResponseBody
    public ModelMap save(@ModelAttribute Role role) throws SaviorFrameworkException {
        ModelMap modelMap = new ModelMap();
        try {
            securityUtils.setCreateEntity(role);// 设置新建数据的操作用户及时间信息
            role.setVersion(OaConstants.VERSION_INIT_VALUE);

            roleService.saveWithFunction(role);

            modelMap.addAttribute(OaConstants.DEFAULT_SUCCESS_KEY, Boolean.TRUE);
            modelMap.addAttribute(OaConstants.DEFAULT_ID_KEY, role.getId());
            logger.info(messages.getMessage("log.info.create",
                    new String[]{securityUtils.getUserFullName(), messages.getMessage(domain), role.getId()}));
        } catch (Exception e) {
            e.printStackTrace();
            modelMap.addAttribute(OaConstants.DEFAULT_SUCCESS_KEY, Boolean.FALSE);
            modelMap.addAttribute(OaConstants.DEFAULT_ERROR_KEY, e.getMessage());
            logger.error(messages.getMessage("log.error.create", new String[]{securityUtils.getUserFullName(), messages.getMessage(domain)}));
        }
        return modelMap;
    }

    @RequestMapping(value = "/edit", method = RequestMethod.GET)
    public String edit() throws SaviorFrameworkException {
        return viewPrefix + "edit";
    }

    /**
     * 更新编辑数据
     *
     * @param id
     * @param request
     * @return
     * @throws SaviorFrameworkException
     */
    @RequestMapping(value = "/edit/{id}", method = RequestMethod.POST)
    @ResponseBody
    public ModelMap update(@PathVariable("id") String id, HttpServletRequest request) throws SaviorFrameworkException {
        ModelMap modelMap = new ModelMap();
        try {
            Role role = roleService.get(id);
            ServletRequestDataBinder binder = new ServletRequestDataBinder(role);
            binder.bind(request);
            securityUtils.setModifyEntity(role);
            role.setVersion(role.getVersion() + 1);
            roleService.update(role);

            modelMap.addAttribute(OaConstants.DEFAULT_SUCCESS_KEY, Boolean.TRUE);
            logger.info(messages.getMessage("log.info.edit", new String[]{securityUtils.getUserFullName(), messages.getMessage(domain), id}));
        } catch (Exception e) {
            e.printStackTrace();
            modelMap.addAttribute(OaConstants.DEFAULT_SUCCESS_KEY, Boolean.FALSE);
            modelMap.addAttribute(OaConstants.DEFAULT_ERROR_KEY, e.getMessage());
            logger.error(messages.getMessage("log.error.edit", new String[]{securityUtils.getUserFullName(), messages.getMessage(domain), id}));
        }
        return modelMap;
    }

    @RequestMapping(value = "/view/{id}", method = RequestMethod.GET)
    @ResponseBody
    public ModelMap get(@PathVariable("id") String id) throws SaviorFrameworkException {
        ModelMap modelMap = new ModelMap();
        try {
            modelMap.addAttribute(OaConstants.DEFAULT_RECORD_MODEL_KEY, roleService.findById(id));
            modelMap.addAttribute(OaConstants.DEFAULT_SUCCESS_KEY, Boolean.TRUE);
        } catch (Exception e) {
            e.printStackTrace();
            modelMap.addAttribute(OaConstants.DEFAULT_SUCCESS_KEY, Boolean.FALSE);
            modelMap.addAttribute(OaConstants.DEFAULT_ERROR_KEY, e.getMessage());
        }
        return modelMap;
    }

    @RequestMapping(value = "/delete", method = RequestMethod.DELETE)
    @ResponseBody
    public ModelMap delete(@RequestParam(value = "ids", required = true) String[] ids) throws SaviorFrameworkException {
        ModelMap modelMap = new ModelMap();
        try {
            roleService.deleteByIds(ids);
            modelMap.addAttribute(OaConstants.DEFAULT_SUCCESS_KEY, Boolean.TRUE);
            logger.info(messages.getMessage("log.info.delete", new String[]{securityUtils.getUserFullName(), messages.getMessage(domain),
                    StringUtils.arrayToDelimitedString((Object[]) ids, "|")}));
        } catch (Exception e) {
            e.printStackTrace();
            modelMap.addAttribute(OaConstants.DEFAULT_SUCCESS_KEY, Boolean.FALSE);
            modelMap.addAttribute(OaConstants.DEFAULT_ERROR_KEY, e.getMessage());
            logger.error(messages.getMessage("log.error.delete", new String[]{securityUtils.getUserFullName(), messages.getMessage(domain),
                    StringUtils.arrayToDelimitedString((Object[]) ids, "|")}));
        }
        return modelMap;
    }

    //----分配功能--------------------------------------------------------------------------------------------------------------------
    @RequestMapping(value = "/function", method = RequestMethod.GET)
    public String function() throws SaviorFrameworkException {
        return viewPrefix + "function";
    }

    @RequestMapping(value = "/function/{role}", method = RequestMethod.GET)
    @ResponseBody
    public List<Map<String, Object>> function(@PathVariable("role") String role, HttpServletResponse response, HttpServletRequest request)
            throws SaviorFrameworkException, IOException {
        String id = request.getParameter("id");
        if (org.apache.commons.lang.StringUtils.isEmpty(id)) {
            List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
            id = "TREE_ROOT_NODE";
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("id", id);
            map.put("name", messages.getMessage("function"));
            map.put("nocheck", true);
            map.put("children", functionService.findModuleAndFunctionByRole(id, role));

            list.add(map);
            return list;
        } else {
            return functionService.findModuleAndFunctionByRole(id, role);
        }

        /*String id = request.getParameter("node");
        return functionService.findModuleAndFunctionByRole(id, role);*/
    }

    @RequestMapping(value = "/function", method = RequestMethod.POST)
    @ResponseBody
    public ModelMap function(HttpServletRequest request,
                             @RequestParam("role") String role) throws SaviorFrameworkException {
        ModelMap modelMap = new ModelMap();
        String[] checkedIds = request.getParameterValues("checked");
        try {
            roleService.saveRoleFunction(checkedIds, role);
            //TODO:是否要处理shiro的事项

            modelMap.addAttribute(OaConstants.DEFAULT_SUCCESS_KEY, Boolean.TRUE);
        } catch (Exception e) {
            e.printStackTrace();
            modelMap.addAttribute(OaConstants.DEFAULT_SUCCESS_KEY, Boolean.FALSE);
            modelMap.addAttribute(OaConstants.DEFAULT_ERROR_KEY, e.getMessage());
        }
        return modelMap;
    }


    //----分配menu-------------------------------------------------------------------------------------------------------
    @RequestMapping(value = "/menu", method = RequestMethod.GET)
    public String assignMenu() throws SaviorFrameworkException {
        return viewPrefix + "menu_assign";
    }

    @RequestMapping(value = "/menu/{role}", method = RequestMethod.GET)
    @ResponseBody
    public List<Map<String, Object>> assignMenu(@PathVariable("role") String role,
                                                HttpServletRequest request) throws SaviorFrameworkException {
        String id = request.getParameter("id");
        if (org.apache.commons.lang.StringUtils.isEmpty(id)) {
            List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
            id = "TREE_ROOT_NODE";
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("id", id);
            map.put("name", messages.getMessage("menu"));
            map.put("nocheck", true);
            map.put("children", menuService.findByRole(id, role));

            list.add(map);
            return list;
        } else {
            return menuService.findByRole(id, role);
        }
    }

    @RequestMapping(value = "/menu", method = RequestMethod.POST)
    @ResponseBody
    public ModelMap assignMenu(HttpServletRequest request, @RequestParam("role") String role) throws SaviorFrameworkException {
        ModelMap modelMap = new ModelMap();
        String[] menus = request.getParameterValues("menus");
        try {
            roleService.saveRoleMenu(menus, role);
            modelMap.addAttribute(OaConstants.DEFAULT_SUCCESS_KEY, Boolean.TRUE);
        } catch (Exception e) {
            e.printStackTrace();
            modelMap.addAttribute(OaConstants.DEFAULT_SUCCESS_KEY, Boolean.FALSE);
            modelMap.addAttribute(OaConstants.DEFAULT_ERROR_KEY, e.getMessage());
        }
        return modelMap;
    }

    // -----分配用户-----------------------------------------------------------------------------------------------------------

    @RequestMapping(value = "/userassign", method = RequestMethod.GET)
    public String assignUser() throws SaviorFrameworkException {
        return viewPrefix + "user_assign";
    }

    @RequestMapping(value = "/user/{role}", method = RequestMethod.POST)
    @ResponseBody
    public List<Map<String, Object>> assignUser(
            @PathVariable("role") String role,
            HttpServletRequest request) throws SaviorFrameworkException {
        String orgId = request.getParameter("id");
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        if (org.apache.commons.lang.StringUtils.isEmpty(orgId)) {
            orgId = securityUtils.getUser().getOrg().getId();
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("id", orgId);
            map.put("name", securityUtils.getUser().getOrg().getName());
            map.put("nocheck", true);
            List<Map<String, Object>> children = new ArrayList<Map<String, Object>>();

            List<Map<String, Object>> orgs = orgService.findByRole(orgId, role);
            List<Map<String, Object>> users = userService.findByOrgAndRole(orgId, role);
            for (Map org : orgs) {
                org.put("nocheck", true);
                org.put("isParent", true);//展开部门节点
            }
            children.addAll(users);
            children.addAll(orgs);

            map.put("children", children);
            list.add(map);
        } else {
            List<Map<String, Object>> orgs = orgService.findByRole(orgId, role);
            List<Map<String, Object>> users = userService.findByOrgAndRole(orgId, role);
            for (Map org : orgs) {
                org.put("nocheck", true);
                org.put("isParent", true);
            }
            list.addAll(users);
            list.addAll(orgs);
        }
        return list;
    }

    @RequestMapping(value = "/usersave", method = RequestMethod.POST)
    @ResponseBody
    public ModelMap saveRoleUser(@RequestParam(value = "checked", required = false) String[] checked,
                                 @RequestParam(value = "unchecked", required = false) String[] unchecked,
                                 @RequestParam(value = "role", required = false) String role) throws SaviorFrameworkException {
        ModelMap modelMap = new ModelMap();
        try {
            if (checked == null) {
                checked = new String[]{};
            }
            if (unchecked == null) {
                unchecked = new String[]{};
            }
            roleService.saveRoleUser(checked, unchecked, role);
            modelMap.addAttribute(OaConstants.DEFAULT_SUCCESS_KEY, Boolean.TRUE);
        } catch (Exception e) {
            e.printStackTrace();
            modelMap.addAttribute(OaConstants.DEFAULT_SUCCESS_KEY, Boolean.FALSE);
            modelMap.addAttribute(OaConstants.DEFAULT_ERROR_KEY, e.getMessage());
        }
        return modelMap;
    }

    @RequestMapping(value = "/select", method = RequestMethod.GET)
    public String selectPage() throws SaviorFrameworkException {
        return viewPrefix + "select";
    }
}
